﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using MyTask.Application.Services;
using MyTask.Domain.Commands;
using MyTask.Domain.Models;
using MyTask.Domain.Queries;
using MyTask.Infrastructure.Context;
using Newtonsoft.Json.Linq;

namespace MyTask.WebApi.Controllers
{
    [Route("api/user")]
    [ApiController]
    public class UserController : ControllerBase
    {

        #region Private variable
        private readonly IConfiguration _configuration;
        private readonly IUserInfoService _userInfoService;
        #endregion
        #region Constructor
        public UserController(IConfiguration configuration, IUserInfoService userInfoService)
        {
            _configuration = configuration;
            _userInfoService = userInfoService;
        }
        #endregion
        #region Public Api
        /// <summary>
        /// Register a user
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [Route("register")]
        [HttpPost]
        public ActionResult Register(UserInfoCommand command)
        {
            bool result = false;
            if (ModelState.IsValid)
            {
                result = _userInfoService.Register(command);
            }
           
            return Ok(result);
        }
        /// <summary>
        /// Log in
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [Route("login")]
        [HttpPost]
        public ActionResult Login(LoginQuery query)
        {
            if (string.IsNullOrEmpty(query.UserName) || string.IsNullOrEmpty(query.Password))
            {
                return NotFound("Please fill in username and password");
            }
            if (!_userInfoService.Login(query))
            {
                return NotFound("User name not found.");
            }
            string securityKey = _configuration.GetSection("JwtSetting:SecurityKey").Value;
            string issuer = _configuration.GetSection("JwtSetting:Issuer").Value;
            string audience = _configuration.GetSection("JwtSetting:Audience").Value;
            var claims = new[] { new Claim(ClaimTypes.NameIdentifier, query.UserName) };
            var now = DateTime.Now;
            var ex = now + TimeSpan.FromMinutes(30);
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var token = new SecurityTokenDescriptor
            {
                Issuer = issuer,
                Audience = audience,
                Expires = ex,
                IssuedAt = now,
                SigningCredentials = creds,
                Subject = new ClaimsIdentity(claims)
            };
            string tokenStr = new JwtSecurityTokenHandler().CreateEncodedJwt(token);
            return Ok(tokenStr);
        }
        /// <summary>
        /// Login Successful
        /// </summary>
        /// <returns></returns>
        [Route("users")]
        [HttpGet]
        public ActionResult LoginSuccess()
        {
            return Ok("Login Successful!");
        }
        /// <summary>
        /// Get user by username
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [Route("userName")]
        [HttpPost]
        [Authorize]
        public ActionResult GetUserInfoByUserName(GetUserInfoByUserNameQuery query)
        {
            var userInfo = _userInfoService.GetUserInfoByUserName(query);
            if (userInfo == null) {
                return NotFound();
            }
            return Ok(userInfo);
        }
        /// <summary>
        /// Get shared users
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        [Route("shareduser")]
        [HttpPost]
        [Authorize]
        public ActionResult GetSharedUsers(GetSharedUsersQuery query)
        {
            var result = _userInfoService.GetSharedUsers(query);
            return Ok(result);
        } 
        #endregion
    }
}